package org.web.clientlistmanager.server.runner;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.web.base.domain.helper.ServiceExceptionHelper;
import org.web.clientlistmanager.sdk.dto.ClmRequest;
import org.web.clientlistmanager.sdk.event.EventHelper;
import org.web.clientlistmanager.server.biz.ClmBatchBizImpl;
import org.web.clientlistmanager.server.biz.ClmReportSelfEvent;
import org.web.clientlistmanager.server.domain.ClientProcessDO;
import org.web.clientlistmanager.server.domain.query.QueryClientProcess;
import org.web.clientlistmanager.server.service.ClientProcessService;
import org.web.clientlistmanager.sdk.event.EventInterface;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@ChannelHandler.Sharable
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = Logger.getLogger(NettyServerHandler.class);

    @Resource
    private ClmReportSelfEvent clmReportSelfEvent;

    @Resource
    private ClientProcessService clientProcessService;

    @Autowired
    private ApplicationContext applicationContext;

    @Resource
    private ClmBatchBizImpl clmBatchBiz;

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) {
        System.out.println("ServerSide channelRegistered");
        ctx.fireChannelRegistered();

    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        // 新连接加入时的处理逻辑
        System.out.println("ServerSide handlerAdded");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) {
        System.out.println("ServerSide channelUnregistered");
        ctx.fireChannelUnregistered();

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("333333333");
        ctx.fireChannelActive();

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        ctx.channel().eventLoop().schedule(new Runnable() {
            @Override
            public void run() {
                String processMark = clmReportSelfEvent.getChannelMap().get(ctx.channel().id().asLongText());
                try {
                    if (StringUtils.isNotBlank(processMark)) {
                        QueryClientProcess queryClientProcess = new QueryClientProcess();
                        queryClientProcess.setProcessUuid(processMark);
                        ClientProcessDO clientProcessDO = clientProcessService.selectOneClientProcess(queryClientProcess);
                        if (clientProcessDO != null) {
                            long notSendHeartBeatTime = System.currentTimeMillis() - clientProcessDO.getUpdateTime().getTime();
                            if (notSendHeartBeatTime > 30 * 1000) {
                                List<String> processUuidList = new ArrayList<>();
                                processUuidList.add(processMark);
                                clmBatchBiz.deleteRegisteredInfoByProcessUuidList(processUuidList);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error(ServiceExceptionHelper.getExceptionInfo(e));
                } finally {
                    clmReportSelfEvent.getChannelMap().remove(ctx.channel().id().asLongText());
                }
            }
        }, 31, TimeUnit.SECONDS);//5秒后执行
        ctx.fireChannelInactive();

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        List<ClmRequest> list = EventHelper.parseRequest(msg);
        for (ClmRequest clmRequest : list) {
            // TODO 注入异常，试试
            try {
                EventInterface execute = applicationContext.getBean(clmRequest.getEventName(), EventInterface.class);
                execute.executeRequest(clmRequest, ctx);
            } catch (Exception e) {
                logger.error(ServiceExceptionHelper.getExceptionInfo(e));
            }
        }
        ctx.fireChannelRead(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("666666");
        ctx.fireChannelReadComplete();

    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        System.out.println("77777777");
        ctx.fireUserEventTriggered(evt);

    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) {
        System.out.println("8888888");
        ctx.fireChannelWritabilityChanged();

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.out.println("9999999999");
        ctx.channel().id();
        ctx.fireExceptionCaught(cause);
    }
}
